package net.vkits.common.aop;

import net.vkits.admin.application.SyslogApplicationService;
import net.vkits.admin.domain.model.Syslog;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.Enumeration;

/**
 * Created by ethan-liu on 16/4/13.
 */
@Aspect
@Component
public class SysLogAop {
    private static Logger LOGGER = LoggerFactory.getLogger(SysLogAop.class);

    @Resource
    private SyslogApplicationService syslogApplicationService;

    @Pointcut("execution(* net.vkits.controller..*.*(..))")
    public void cutController() {}

    @Around("cutController()")
    public Object aroundAdvice(ProceedingJoinPoint point) throws Throwable {
        String methodName = point.getSignature().getName();
        String className = point.getTarget().getClass().getName();
        Object[] params = point.getArgs();
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        String clientIp = request.getRemoteAddr();
        StringBuffer bfParams = this.getParams(params);
        final Subject subject = SecurityUtils.getSubject();
        PrincipalCollection collection = subject.getPrincipals();
        if (null != collection) {
            String loginName = (String) subject.getPrincipals().getPrimaryPrincipal();
            String strMessage = String
                    .format("[操作人]:%s,[类名]:%s,[方法]:%s,[参数]:%s", loginName, className, methodName, bfParams.toString());
            LOGGER.info(strMessage);
            syslogApplicationService.insertLog(new Syslog(loginName, strMessage,clientIp ));
        }
        return point.proceed();
    }

    private StringBuffer getParams(Object[] params) {
        StringBuffer bfParams = new StringBuffer();
        if (params != null && params.length > 0) {
            HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
            Enumeration<String> paraNames = request.getParameterNames();
            String key;
            String value;
            while (paraNames.hasMoreElements()) {
                key = paraNames.nextElement();
                value = request.getParameter(key);
                bfParams.append(key).append("=").append(value).append("&");
            }
            if (StringUtils.isBlank(bfParams)) {
                bfParams.append(request.getQueryString());
            }
            LOGGER.info(request.getRemoteAddr());
        }
        return bfParams;
    }
}
